使用缓冲提高文件I/O效率
缓冲区的大小对性能有很大的影响, 原因是系统调用需要在用户-内核之间转换, 会消耗很多时间
使用缓冲的who命令
原来的who
命令每次只取一个用户, 大大浪费了时间, 我们可以一次取16条记录,
首先编写 utmplib.c
#include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <utmp.h> #include <unistd.h> #define NRECS 16 #define NULLUT ((struct utmp *)NULL) // 将NULL指针强制转化成 struct utmp指针 #define UTSIZE (sizeof(struct utmp)) static char utmpbuf[NRECS * UTSIZE]; static int num_recs; static int cur_rec; static int fd_utmp = -1; int utmp_reload(); int utmp_open(char * filename) { fd_utmp = open(filename, O_RDONLY); cur_rec = num_recs = 0; return fd_utmp; } struct utmp *utmp_next() { struct utmp *recp; if (fd_utmp == -1) return NULLUT; if (cur_rec == num_recs && utmp_reload() == 0) return NULLUT; recp = (struct utmp *) &utmpbuf[cur_rec * UTSIZE]; cur_rec++; return recp; } int utmp_reload() { int amt_read; amt_read = read(fd_utmp, utmpbuf, NRECS * UTSIZE); num_recs = amt_read/UTSIZE; cur_rec = 0; return num_recs; } void utmp_close() { if (fd_utmp != -1) close(fd_utmp); } /** * 变量 num_recs记录了缓冲区中的数据个数, * 变量 cur_rec 记录了缓冲区已被使用的数据个数 * 每次从缓冲区中读数据前, 先检查 cur_rec 的值是否登陆 num_recs, * 如果相等说明缓冲区已经没有可用句库, 就调用 read 从硬盘上读数据 * 来填满缓冲区, 在返回数据前, 增加cur_rec的值 * 函数 utmp_next 返回指向结构的指针, */
然后根据utmplib.c
提供的接口编写who3.c
#include <stdio.h> #include <sys/types.h> #include <utmp.h> #include <fcntl.h> #include <time.h> #define SHOWHOST void show_info(struct utmp *); void show_time(time_t); int main() { struct utmp *utbufp, *utmp_next(); if (utmp_open(UTMP_FILE) == -1) { perror(UTMP_FILE); return -1; } while ((utbufp = utmp_next()) != ((struct utmp *) NULL)) show_info(utbufp); utmp_close(); return 0; } void show_info(struct utmp * utbufp) { if (utbufp->ut_type != USER_PROCESS) return; printf("%-8.8s", utbufp->ut_user); printf(" "); printf("%-8.8s", utbufp->ut_line); show_time(utbufp->ut_tv.tv_sec); #ifdef SHOWHOST printf("(%s)", utbufp->ut_host); #endif printf("\n"); } void show_time(long timeval) { char *cp; cp = ctime(&timeval); printf("%12.12s", cp + 4); }
utmplib.c
提供了简单清晰的操作缓冲区的接口, 并隐藏了细节,who3.c
可以根据utmplib.c
很容易的写出使用缓冲区的who
然后编译
cc utmplib.c who3.c -o who3